﻿Imports System.Runtime.InteropServices
Imports System.Drawing

Public Class PixelData
    Private m_Height As Integer
    Private m_Width As Integer
    Private m_data As Byte(,)
    Private m_Overlay As Byte(,)
    Public Property Width() As Integer
        Get
            Return m_Width
        End Get
        Set(ByVal value As Integer)
            m_Width = value
        End Set
    End Property
    Public Property Height() As Integer
        Get
            Return m_Height
        End Get
        Set(ByVal value As Integer)
            m_Height = value
        End Set
    End Property
    Public Property Pixel() As Byte(,)
        Get
            Return m_data
        End Get
        Set(ByVal value As Byte(,))
            m_data = value
        End Set
    End Property
    Public Property Overlay() As Byte(,)
        Get
            Return m_Overlay
        End Get
        Set(ByVal value As Byte(,))
            m_Overlay = value
        End Set
    End Property
    Public Sub New(ByVal Data As Imaging.BitmapData)
        m_Height = Data.Height
        m_Width = Data.Width
        Dim t_data(m_Width, m_Height) As Byte
        Dim o_data(m_Width, m_Height) As Byte
        For y = 0 To Data.Height - 1
            For x = 0 To Data.Width - 1
                t_data(x, y) = Marshal.ReadByte(Data.Scan0, (Data.Stride * y) + x)
                o_data(x, y) = 0
            Next
        Next
        m_data = t_data
        m_Overlay = o_data
    End Sub
    Public Sub New(ByVal Source As Bitmap)
        Dim Data As Imaging.BitmapData = Source.LockBits(New Rectangle(0, 0, Source.Width, Source.Height), Imaging.ImageLockMode.ReadOnly, Source.PixelFormat)
        m_Height = Data.Height
        m_Width = Data.Width
        Dim t_data(m_Width, m_Height) As Byte
        Dim O_Data(m_Width, m_Height) As Byte
        For y = 0 To Data.Height - 1
            For x = 0 To Data.Width - 1
                t_data(x, y) = Marshal.ReadByte(Data.Scan0, (Data.Stride * y) + x)
                O_Data(x, y) = 0
            Next
        Next
        Source.UnlockBits(Data)
        m_data = t_data
        m_Overlay = O_Data
    End Sub
    Public Function GetBitmap() As Bitmap
        Dim Bmp As New Bitmap(m_Width, m_Height, Imaging.PixelFormat.Format8bppIndexed)
        Dim Pal As Imaging.ColorPalette = Bmp.Palette
        For c = 0 To 255
            Pal.Entries(c) = Color.FromArgb(c, c, c)
        Next
        Bmp.Palette = Pal
        Dim BmData As Imaging.BitmapData = Bmp.LockBits(New Rectangle(0, 0, m_Width, m_Height), Imaging.ImageLockMode.WriteOnly, Bmp.PixelFormat)
        Dim bV As Byte
        For y = 0 To BmData.Height - 1
            For x = 0 To BmData.Width - 1
                bV = m_data(x, y)
                Marshal.WriteByte(BmData.Scan0, (BmData.Stride * y) + x, bV)
            Next
        Next
        Bmp.UnlockBits(BmData)
        Return Bmp
    End Function
    Public Function GetColorBitmap(ByVal OverlayColor As Color) As Bitmap
        Dim Bmp As New Bitmap(m_Width, m_Height, Imaging.PixelFormat.Format32bppArgb)
        Dim BmData As Imaging.BitmapData = Bmp.LockBits(New Rectangle(0, 0, m_Width, m_Height), Imaging.ImageLockMode.WriteOnly, Bmp.PixelFormat)
        Dim bV As Byte
        Dim Red As Byte
        Dim Green As Byte
        Dim Blue As Byte
        Dim Alpha As Byte
        For y = 0 To BmData.Height - 1
            For x = 0 To BmData.Width - 1
                If m_Overlay(x, y) > 0 Then
                    Red = OverlayColor.R
                    Green = OverlayColor.G
                    Blue = OverlayColor.B
                    Alpha = OverlayColor.A
                Else
                    bV = m_data(x, y)
                    Red = bV
                    Green = bV
                    Blue = bV
                    Alpha = 255
                End If
                Marshal.WriteByte(BmData.Scan0, (BmData.Stride * y) + (x * 4), Blue)
                Marshal.WriteByte(BmData.Scan0, (BmData.Stride * y) + (x * 4) + 1, Green)
                Marshal.WriteByte(BmData.Scan0, (BmData.Stride * y) + (x * 4) + 2, Red)
                Marshal.WriteByte(BmData.Scan0, (BmData.Stride * y) + (x * 4) + 3, Alpha)
            Next
        Next
        Bmp.UnlockBits(BmData)
        Return Bmp
    End Function
End Class
